﻿package rmhc.api.vk
{
	import com.adobe.images.PNGEncoder;
	import flash.display.BitmapData;
	import flash.events.Event;
	import flash.events.KeyboardEvent;
	import flash.events.TimerEvent;
	import flash.system.LoaderContext;
	import flash.system.Security;
	import flash.utils.Timer;
	import flash.utils.getTimer;
	import flash.utils.setTimeout;
	import rmhc.api.dataflow.AlbumInfo;
	import rmhc.api.dataflow.PhotoInfo;
	import rmhc.api.dataflow.UserInfo;
	import rmhc.api.tasks.IApiTask;
	import rmhc.api.tasks.IGetAlbums;
	import rmhc.api.tasks.IGetPhotos;
	import rmhc.api.tasks.IGetUserInfo;

	import rmhc.RMHCApp;
	
	import rmhc.api.ApiWrapper;
	import rmhc.api.dataflow.WallPostInfo;
	import rmhc.api.tasks.BaseApiTask;
	import rmhc.api.tasks.IGetFriends;
	import rmhc.api.tasks.IGetProfilePicture;
	import rmhc.api.tasks.IGetProfileThumb;
	import rmhc.api.tasks.IPrepareProfileUpload;
	import rmhc.api.tasks.ISetProfilePicture;
	import rmhc.api.tasks.IWallPost;
	import rmhc.gui.SupplyFunctions;
	import rmhc.gui.customTrace;
	
	import vk.APIConnection;
	import vk.events.CustomEvent;
	
	public class VkApi extends ApiWrapper
	{
		protected var vars:Object;
		protected var conn:APIConnection;
		protected var timers:Vector.<int> = new Vector.<int>();
		protected var profileUploadUrl:String;
		protected var me:UserInfo;
		protected var queue:Vector.<VkApiTask> = new Vector.<VkApiTask>();
		protected var wallUploadURL:String;
		//protected var tm:Timer;
		
		public function VkApi( vars:Object )
		{
			super();
			this.vars = vars;
			customTrace("VkApi:VkApi:" +SupplyFunctions.objectToString(vars));
			
						//tm = new Timer( 350 );
			//tm.addEventListener( TimerEvent.TIMER , tryNextCall );
		}
		
		override public function connect():void
		{
			trace( "connect begin" );
			//Security.loadPolicyFile('http://vk.com/crossdomain.xml');
			//Security.loadPolicyFile('http://vkontakte.ru/crossdomain.xml');
			Security.allowDomain( "*" );
			Security.allowDomain( "*.vk.com" );
			Security.allowDomain( "*.vkontakte.ru" );
			conn = new APIConnection( vars );
			//conn.addEventListener(CustomEvent.CONN_INIT, conn_connInit);
			//dispatchEvent( new Event( Event.CONNECT ) );
			var t:GetUserInfoTask = loadMe() as GetUserInfoTask;
			t.addEventListener(Event.COMPLETE, loadMe_complete);
			t.run();
		}
		public function getWallUploadUrl():String {
			if (wallUploadURL) {
				return wallUploadURL;
			}
			throw(new Error("Error in VkApi:getWallUploadUrl. небыла выполнена команда preparePostToWall(), а значит я не знаю куда грузить фотку для отправки на стену."));
			return null;
		}
		public function setWallUploadUrl(url:String):void {
			
			wallUploadURL = url;

		}
		private function loadMe_complete(e:Event):void {
			customTrace("VkApi:loadMe_complete:" );
			me = (e.target as IGetUserInfo).getUserInfo();
			dispatchEvent( new Event( Event.CONNECT ) );
			return;//дальнейшее - для моего локального теста.
			//localTest();
		}
		

		private function loadMe():IGetUserInfo {
			customTrace("VkApi:loadMe:" );
			var t:GetUserInfoTask = new GetUserInfoTask(this, getUID());
			addTask( t );
			return  t;
		}
		private function conn_connInit(e:CustomEvent):void 
		{
			trace( "VK api connected" );
			
		}
		
		override public function getAppUrl():String
		{
			return "http://vkontakte.ru/app2661805";
		}
		override public function getLadoshkId():String
		{
			//TODO: здесь будет статичный ИД картинки с ладошкой
			return "photo34722749_271135276";
		}
		override public function getNetworkId():int
		{
			return VK;
		}
		override public function getUID():String
		{
			return vars['viewer_id'];
		}
		override public function prepareProfileUpload():IPrepareProfileUpload
		{
			var t:PrepareProfileUpload = new PrepareProfileUpload( this );
			addTask( t );
			return  t;
		}
		override public function getProfileThumb( profileId:String ):IGetProfileThumb
		{
			throw(new Error("Error in VkApi:getProfileThumb. "));
			return null;
		}
		override public function getProfilePicture( profileId:String ):IGetProfilePicture
		{
			customTrace("VkApi:getProfilePicture:" );
			var t:GetProfilePicture = new GetProfilePicture( this , profileId );
			addTask( t );
			return  t;
		}
		override public function setProfilePicture(picture:BitmapData ):ISetProfilePicture
		{
			customTrace("VkApi:setProfilePicture:" );
			if (!profileUploadUrl) {
				throw(new Error("Error in VkApi:setProfilePicture. profileUploadUrl = '"+profileUploadUrl+"'."));
			}
			var t:UploadProfilePhoto = new UploadProfilePhoto(this, picture, profileUploadUrl);
			addTask(t);
			return  t;
		}

		override public function postToWall( post:WallPostInfo ):IWallPost
		{
			var t:BaseApiTask;
			if ( !post.wallId )
			{
				post.wallId = me.uid;
			}
			if(post.postType==WallPostInfo.MEDIA){
				t = new WallPost(this,post);
			}else if(post.postType==WallPostInfo.APP){
				t = new WallSavePost(this, post);
			}else {
				throw(new Error("Error in VkApi:postToWall. post.postType не равен MEDIA и не равен APP, а равен '"+post.postType+"'"));
			}
			addTask(t);
			return  t as IWallPost;
		}
		public function saveWallPost(hash:String):void {
			conn.callMethod("saveWallPost", hash);
		}
		override public function getFriends():IGetFriends
		{
			customTrace("VkApi:getFriends:" );
			var t:GetFriends = new GetFriends( this );
			addTask( t );
			return t;
		}
		//public function setWallUploadUrl( url:String ):void {
		//			wallUploadUrl = url;
		//}
		public function setProfileUploadUrl( url:String ):void
		{
			profileUploadUrl = url;
			//задаём урл для загрузки фотки в профиль
		}
		override public function preparePostToWall( ):IApiTask {
			var t:PrepareWallPostTask = new PrepareWallPostTask(this);
			addTask(t);
			return  (t as IApiTask);
		}
		public function getProfileUploadUrl():String
		{
			if(profileUploadUrl)
				return profileUploadUrl;
			throw(new Error("Error in VkApi:getProfileUploadUrl. profileUploadUrl = '" + profileUploadUrl + "'"));
			return "Error in VkApi:getProfileUploadUrl. profileUploadUrl = '" + profileUploadUrl + "'";
		}
		//public function getWallUploadUrl():String
		//{
		//	if(wallUploadUrl)
		//		return wallUploadUrl;
		//	throw(new Error("Error in VkApi:getWallUploadUrl. wallUploadUrl = '" + wallUploadUrl + "'"));
		//	return "Error in VkApi:getWallUploadUrl. wallUploadUrl = '" + wallUploadUrl + "'";
		//}		
		override public function runTask( t:BaseApiTask ):Boolean
		{
			customTrace("VkApi:runTask:" +SupplyFunctions.objectToString(t));
			if ( !super.runTask( t ) )
			{
				customTrace("runTask return false;");
				return false;
			}
			callTask( t as VkApiTask );
			return true;
		}
		override public function getMe():UserInfo 
		{
			return me;
		}
		private function callTask( t:VkApiTask ):void
		{
			if ( t.getMethod() == null )
			{
				return;
			}
			queue.push( t );
			//Stamper.debug( "try call: " + task.method );
			t.setParam( "format" , "JSON" );
			//task.params.test_mode = "1";
			t.addEventListener( Event.COMPLETE , tryNextCall );
			//tasks.push( t );
			tryNextCall();
		}
		protected function tryNextCall( e:Event = null ):void
		{
			if ( queue.length == 0 )
			{
				return;
			}
			
			if ( canCall() )
			{
				var t:VkApiTask = getNextTask();
				customTrace( "calling task: " + t.getMethod());
				if ( t == null )
				{
					return;
				}
				customTrace("VkApi:tryNextCall:" +"t.getMethod() = " + t.getMethod() + ", t.getParams() =  " + SupplyFunctions.objectToString(t.getParams()) + ", t.parseData = " + t.parseData + ", t.onError = " + t.onError);
				conn.api( t.getMethod() , t.getParams() , t.parseData , t.onError);
				//conn.api( t.getMethod() , t.getParams() , t.parseData , onErrorHandler); - ДЛЯ МОИХ ТЕСТОВ(МИК)
				customTrace("VkApi:tryNextCall: conn called" );
			}
			else
			{
				setTimeout( tryNextCall , timers[timers.length - 3] - getTimer() + 1200 );
			}
		}
		protected function getNextTask():VkApiTask
		{
			if ( queue.length == 0 )
			{
				return null;
			}
			var t:VkApiTask;
			do
			{
				t = queue.shift() as VkApiTask;
			} while ( t.getMethod() == null && queue.length > 0 );
			
			if ( t != null && t.getMethod() != null )
			{
				timers.push( getTimer() );
				return t;
			}
			return null;
		}
		private function debugOnComplete(...arguments):void {
			customTrace("VkApi:debugOnComplete: debug..." );
			customTrace("VkApi:debugOnComplete: arguments = "+ arguments);
			for (var i:int = 0; i < arguments.length; i++) 
			{
				customTrace("VkApi:debugOnComplete:" +SupplyFunctions.objectToString(arguments[i]));
			}
		}
			
		private function onErrorHandler(...arguments):void {
			customTrace("VkApi:onErrorHandler: debug..." );
			for (var i:int = 0; i < arguments.length; i++) 
			{
				customTrace("VkApi:onErrorHandler:" +SupplyFunctions.objectToString(arguments[i]));
			}
		}
		protected function canCall():Boolean
		{
			if ( timers.length >= 3 && timers[timers.length - 3] >= getTimer() - 1100 )
			{
				return false;
			}
			else
			{
				return true;
			}
		}
		/// фигня для локальных тестов(мик)
		private function localTest():void 
		{
			/*customTrace("VkApi:localTest: ЗАПРАШИВАЕМ УРЛ ДЛЯ ПОСТИНГА НА СТЕНУ " );
			var t:IApiTask = preparePostToWall();
			t.addEventListener(Event.COMPLETE, preparePostToWall_complete);
			t.run();*/
			customTrace("VkApi:localTest: грузим альбомы " );
			var t:IGetPhotos = getPhotos(getUID(),'-6');
			t.addEventListener(Event.COMPLETE, getPhotosDone);
			t.run();
			
		}
		private function getPhotosDone(e:Event):void 
		{
			var photos:Vector.<PhotoInfo> = (e.target as IGetPhotos).getPhotos();
			for (var i:int = 0; i < photos.length; i++) 
			{
				customTrace("VkApi:getPhotosDone:" +photos[i]);
			}
			
		}		
		private function getAlbumsDone(e:Event):void 
		{
			var albums:Vector.<AlbumInfo> = (e.target as IGetAlbums).getAlbums();
			for (var i:int = 0; i < albums.length; i++) 
			{
				customTrace("VkApi:getAlbumsDone:" +albums[i]);
			}
			
		}
		private function getAlbums(uid:String = null, gid:String = null, aids:String = null):IGetAlbums {
			var t:GetAlbumsTask = new GetAlbumsTask(this,uid,gid,aids);
			addTask(t);
			return  (t as IGetAlbums);
		}
		private function getPhotos(uid:String, aid:String, pids:String = null):IGetPhotos{
			var t:GetPhotosTask = new GetPhotosTask(this,uid,aid,pids);
			addTask(t);
			return  (t as IGetPhotos);
		}
		
		private function preparePostToWall_complete(e:Event):void {
			RMHCApp.getApp().stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownAfterPrepare);
		}
		private function keyDownAfterPrepare(keyboardEvent:KeyboardEvent):void {
			RMHCApp.getApp().stage.removeEventListener(KeyboardEvent.KEY_DOWN, keyDownAfterPrepare);
			customTrace("VkApi:keyDownAfterPrepare: RMHCApp.getApp().stage.removeEventListener(KeyboardEvent.KEY_DOWN, keyDownAfterPrepare);" );
			customTrace("VkApi:отправляем пост на стену ОЛЕГА: wall.post...");
			//НИЖЕ - ВАРИАНТ APP
				//var wpi:WallPostInfo = new WallPostInfo(getUID(), "testDescr", "testMessage",WallPostInfo.APP);
				//wpi.thumbPng = PNGEncoder.encode(new BitmapData(100, 100, true, 0xFF0000));
			//А ЭТО - MEDIA
			var wpi:WallPostInfo = new WallPostInfo(getUID(), "testDescr", "testMessage", WallPostInfo.MEDIA);
			wpi.mediaId = getLadoshkId();
			wpi.link = "http://mickfallout.narod.ru/";
			var t:IWallPost = postToWall(wpi);
			t.addEventListener(Event.COMPLETE, postToWall_complete);
			t.run();
		}
		private function postToWall_complete(e:Event):void {
			customTrace("VkApi:postToWall_complete:" );
		}//*/

	}
}